#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <assert.h>

#include "Log.h"
#include "Event.h"
#include "json/json.h"
#include "common.h"
#include "ResData.h"

#include "userPresenter.h"
#include "PlayerPresenter.h"
#include "MapPresenter.h"
#include "EnemyPresenter.h"
#include "BossPresenter.h"
#include "TaskPresenter.h"
#include "NpcPresenter.h"

char logs[1024] = {0};
using std::string;
using namespace std;

typedef void (*msghandler)(string MCmd, string data, ResData& outData);
typedef struct _Msg_handler{
    string moduleID;
    msghandler msgfn;
}Msg_handler_t;

static const Msg_handler_t msg_cmds[] = {
    {"01", userPresenter::userMsgHandler},
    {"02", PlayerPresenter::PlayerMsgHandler},
    {"03", MapPresenter::MapMsgHandler},
    {"04", EnemyPresenter::EnemyMsgHandler},
    {"05", BossPresenter::BossMsgHandler},
    {"06", TaskPresenter::TaskMsgHandler},
    {"07", NpcPresenter::NpcMsgHandler},
};

void msg_handler(int clientfd, string MCmd, string data){

    int i = 0;
    ResData resData;

    if(MCmd.empty() || data.empty()){
        return;
    }

    string moduleId = MCmd.substr(0,2); //截取前两位
    string cmd = MCmd.substr(2,4);
    
    for (i = 0; !msg_cmds[i].moduleID.empty(); ++i)
    {
        if (moduleId != msg_cmds[i].moduleID)
            continue;
            
        msg_cmds[i].msgfn(cmd, data, resData);
        resData.resp_cmd = MCmd;
        std::cout << "res:" << resData.toString();
        std::cout << "------------------------------------------------------" << endl;
        send(clientfd, (resData.toString()).c_str(), resData.toString().length(),0);
        break;
    }
}

void Event::AcceptHandle(int clientfd)
{
    string welcome = "welcome\n";
    sprintf(logs, "client %d connected!",clientfd);
    std::cout << "hello client:" << clientfd << std::endl;
    send(clientfd, welcome.c_str(), welcome.length(), 0);
}

int Event::RecvMessageHandle(int clientfd)
{
    char buf[BUFFER_SIZE] = {0};
    char pkglen[8] = {0};
    int pos = 0;
    char *pbuf = NULL;
    memset(buf, 0, BUFFER_SIZE);
    memset(pkglen, 0, 8);

    int ret = recv(clientfd, buf, BUFFER_SIZE-1, 0);
    pbuf = buf;
    printf("get %d bytes of content: %s", ret, buf);

    while(*pbuf!='\0'){
        char pkglen[8] = {0};
        char onecmd[1024] = {0};
        char *jstart = strchr(pbuf,'{');
        char *jend = strchr(pbuf,'\n');
        strncpy(pkglen, pbuf, (jstart-buf));

        /* if find the end tag, then,it is the all */
        if(jstart == NULL || jend == NULL){
            cout << "no find endler,nd recv again!" << endl;
            static char ttp[1024] = {0};
            if(jend == nullptr){
                strncpy(ttp, jstart, strlen(jstart));
                break;
            }else{
                strcat(ttp, pbuf);
                break;
            }
            cout << "fix data: " << ttp << endl;
        }else{
            strncpy(onecmd, jstart, (jend-jstart));
            pbuf = jend+1;
        }

        cout << "onemd: " << onecmd << endl;

        Json::Value root = Util::init_root(onecmd);
        if(!root["cmd"].isNull()){
            string cmd = root["cmd"].asString();
            pos += atoi(pkglen);

            if(!root["data"].isNull()){
                string data = root["data"].toStyledString();
                cout << "cmd: " << cmd << endl;
                msg_handler(clientfd, cmd, data);
            }
        }
    }

    return ret;
}

int Event::SendBroadcastMessage(int clientfd)
{
    return 0;
}
